package com.uinnova.product.eam.service;

import com.binary.core.io.Resource;
import com.binary.jdbc.Page;
import com.uinnova.product.eam.model.DataModuleRltClassDto;
import com.uinnova.product.eam.model.RltInfoQueryVo;
import com.uinnova.product.eam.model.VcCiRltInfo;
import com.uinnova.product.eam.model.asset.EamCiRltDTO;
import com.uinnova.product.eam.model.vo.ESRltSearchBeanVO;
import com.uinnova.product.vmdb.comm.model.ci.CcCiClass;
import com.uinnova.product.vmdb.provider.ci.bean.CcCiClassInfo;
import com.uinnova.product.vmdb.provider.rlt.bean.CcCiRltInfo;
import com.uino.api.client.cmdb.ICIRltApiSvc;
import com.uino.bean.cmdb.base.ESCIRltInfo;
import com.uino.bean.cmdb.base.LibType;
import com.uino.bean.cmdb.business.BindCiRltRequestDto;
import com.uino.bean.cmdb.business.ImportExcelMessage;
import com.uino.bean.cmdb.business.ImportResultMessage;
import com.uino.bean.cmdb.business.dataset.FriendInfo;
import com.uino.bean.cmdb.business.dataset.UpDownAttrCdt;
import com.uino.bean.cmdb.query.ESAttrAggBean;
import com.uino.bean.cmdb.query.ESRltSearchBean;
import com.uino.bean.permission.base.SysUser;
import com.uino.service.cmdb.microservice.ICIRltSvc;
import org.springframework.web.multipart.MultipartFile;

import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Set;

public interface ICIRltSwitchSvc {

    ICIRltApiSvc getCiRltApiSvc();

    ICIRltSvc getCiRltSvc(LibType libType);

    Long bindCiRlt(BindCiRltRequestDto reqBean, LibType libType);

    /**
     * 批量绑定ci关系
     *
     * @param bindRltDtos
     * @return
     */
    ImportResultMessage bindCiRlts(Set<BindCiRltRequestDto> bindRltDtos, LibType libType);

    /**
     * 根据ciId解除ci关系（无论是目标还是源都解除）
     *
     * @param ciId
     *            源/目标ciId
     * @return 结果
     */
    Integer delRltByCiId(Long ciId, LibType libType);

    /**
     * 根据【关系ids OR 关系codes】解除ci关系
     *
     * @param rltIds 关系ID
     * @param rltCodes 关系Code
     * @param ownerCode 用户code，可空
     * @param libType 库
     * @return 删除结果
     */
    Integer delRltByIdsOrRltCodes(Set<Long> rltIds, Set<String> rltCodes, String ownerCode, LibType libType);

    /**
     * 修改ci关系信息(只能修改属性信息)
     *
     * @param ciRltId
     *            ci关系Id
     * @param attrs
     *            属性信息
     * @return long
     */
    Long updateCiRltAttr(Long ciRltId, Map<String, String> attrs, LibType libType);

    /**
     * 分页查询ci关系（带条件）
     *
     * @param bean 查询条件
     * @return 分页结果信息
     */
    Page<CcCiRltInfo> searchRltByBean(ESRltSearchBean bean, LibType libType);

    /**
     * 根据ids查询ci关系
     *
     * @param ids 关系IDs
     * @return ci关系列表
     */
    List<CcCiRltInfo> searchRltByIds(Set<Long> ids, LibType libType);

    /**
     * 清除某个关系分类下所有ci关系
     *
     * @param rltClassId 关系分类ID
     * @return Integer
     */
    Integer clearRltByClassId(Long rltClassId, LibType libType);

    /**
     * 清除当前用户关系分类下所有ci关系
     *
     * @param rltClassId 关系分类ID
     * @return Integer
     */
    Integer clearUserRltByClassId(Long rltClassId,String ownerCode,LibType libType);


    default Resource exportCiRlt(Set<Long> rltClassIds, LibType libType,String ownerCode){
        return exportCiRlt(rltClassIds, Collections.emptySet(), libType,ownerCode);
    }




    /**
     * 导出ci关系
     *
     * @param rltClassIds
     *            关系分类id
     * @return 资源文件
     */
    Resource exportCiRlt(Set<Long> rltClassIds,Set<Long> rltIds, LibType libType,String ownerCode);

    /**
     * 导入ci关系
     *
     * @param excelFilePath 路径
     * @param excelFile 文件
     * @param rltClsCodes 关系分析Code
     * @return 导入结果
     */
    ImportResultMessage importCiRlt(String excelFilePath, MultipartFile excelFile, Set<String> rltClsCodes, LibType libType);

    /**
     * 解析关系excel
     *
     * @param excelFile
     *            待解析excel
     * @return {关系分类code:是否已存在}
     */
    Map<String, Boolean> comprehendRltExcel(MultipartFile excelFile, LibType libType);

    /**
     * 解析关系excel
     *
     * @param excelFilePath 路径
     * @param excelFile 文件
     * @return 导入结果
     */
    ImportExcelMessage parseRltExcel(String excelFilePath, MultipartFile excelFile, LibType libType);

    /**
     * 分页查询ci关系（带条件）
     *
     * @param bean 查询条件
     * @return 查询结果
     */
    Page<ESCIRltInfo> searchRlt(ESRltSearchBean bean, LibType libType);

    /**
     * 根据分类信息查询关系
     * @param classIds 关系分类id
     * @param sourceClassIds 源端对象分类id
     * @param targetClassIds 目标端对象分类id
     * @param libType 库
     * @return 关系数据
     */
    List<ESCIRltInfo> searchRlt(Set<Long> classIds, Set<Long> sourceClassIds, Set<Long> targetClassIds, LibType libType);

    /**
     * 类sql: select fieldName from table group by fieldName where *****
     *
     * @param req
     *            条件
     * @return 分页查询结果
     */
    Page<String> groupByField(ESAttrAggBean req, LibType libType);

    /**
     * 根据分类筛选条件获取分类关系map
     *
     * @param clsIds
     *            ci分类ids
     * @param rltClsIds
     *            关系分类ids
     * @param libType
     *             库类型（私有/设计/运行）
     * @return {源分类id:{关系分类id:[目标分类ids]}}
     */
    Map<Long, Map<Long, Set<Long>>> getClassRltMapByClsQuery(Set<Long> clsIds, Set<Long> rltClsIds, LibType libType);

    /**
     * 根据分类筛选条件获取分类关系map
     *
     * @param classIds
     *            ci分类ids
     * @param rltClsIds
     *            关系分类ids
     * @param libType
     *             库类型（私有/设计/运行）
     * @return 元模型上使用包含起始分类和目标分类的关系对象信息
     */
    List<DataModuleRltClassDto> getClassRltList(Set<Long> classIds, Set<Long> rltClsIds, LibType libType);

    /**
     * 查询指定CI的上下层关系
     *
     * @param sCiId 需要查询的id
     * @param targetCiClassIds 目标ci
     * @param rltClassIds 关系类型
     * @param up 上层数量
     * @param down 下层数量
     * @param isCache 是否查询缓存数据
     * @return 关系信息
     */
    List<VcCiRltInfo> queryUpAndDownRlt(LibType libType, Long sCiId, List<Long> targetCiClassIds, List<Long> rltClassIds, Integer up, Integer down, Boolean isCache);


    /**
     * 查询指定CI的朋友圈信息(有关联关系CI)
     *
     * @param domainId 域
     * @param startCiId 起始CIID
     * @param ciConditions CI查询条件
     * @param rltConditions 关系查询条件
     * @param rltLvls 关系级别
     * @param upLevel 往上查几层
     * @param downLevel 往下查几层
     * @param hasAttr 是否查询属性信息
     * @param libType 库类型
     * @return FriendInfo 关联信息对象
     */
    FriendInfo queryCiUpDownByCiId(Long domainId, Long startCiId, List<UpDownAttrCdt> ciConditions, List<UpDownAttrCdt> rltConditions,
                                   List<Long> rltLvls, Integer upLevel, Integer downLevel, Boolean hasAttr, LibType libType);

    /**
     * 更加ciCodes查询关系数据
     * @param reqBean
     * @param libType
     * @return
     */
    List<EamCiRltDTO> searchRltByRltCodes(ESRltSearchBean reqBean, LibType libType);

    List<CcCiRltInfo> searchRltByRltUniqueCodesWithoutCi(RltInfoQueryVo rltInfoQueryVo);

    List<CcCiClassInfo> queryAllClasses(LibType libType);

    List<SysUser> findCiRltUserList(ESRltSearchBean reqBean);

    /**
     * 关系扫描
     * @param ciCodes
     * @return
     */
    List<CcCiRltInfo> queryCiBetWeenRlt(List<String> ciCodes);

    /**
     * 批量绑定关系
     * @param reqBean
     * @param libType
     * @return
     */
    List<ESCIRltInfo> bindCiRltBatch(List<BindCiRltRequestDto> reqBean, LibType libType);

    /**
     * 根据rltCode分类查询 分类定义
     *
     * @param rltClassCode
     * @return
     */
    CcCiClassInfo getRltClassByCode(String rltClassCode);

    /**
     * 通过关系分类id，源端分类id，目标端分类id查询关系信息
     * @param rltClassId
     * @param sourceClassId
     * @param targetClassId
     * @param ownerCode
     * @param libType
     * @return
     */
    List<CcCiRltInfo> getRltInfoByClassId(List<Long> rltClassId, Long sourceClassId, Long targetClassId, String ownerCode, LibType libType);

    /**
     * 通过关系code查询
     * @param rltCode 关系code
     * @param ownerCode 用户code
     * @param libType 库
     * @return
     */
    List<CcCiRltInfo> getRltByCode(String rltCode, String ownerCode, LibType libType);

    List<CcCiRltInfo>  searchRltByScroll(ESRltSearchBean rltSearchBean, LibType libType);

    /**
     * 通过关系code查询
     * @param uniqueCodes 唯一标识
     * @param ownerCode 用户标识
     * @param libType 库
     * @return 关系集合
     */
    List<ESCIRltInfo> getRltByUniqueCodes(Set<String> uniqueCodes, String ownerCode, LibType libType);

    /**
     * 通过关系分类ids查关系分类列表
     * @param rltClassIds
     * @return
     */
    List<CcCiClassInfo> queryClassesByRltClassIds(List<Long> rltClassIds);

    boolean findNonCompliance(Long rltClassId,LibType libType);

    Page<CcCiRltInfo> searchRltByBeanVO(ESRltSearchBeanVO reqBean, LibType libType);

    Resource exportCiRltByConditions(ESRltSearchBeanVO reqBean, LibType libType, String ownerCode);

    /**
     * 根据元模型及ci分类过滤关系分类
     * @param sourceClassId ci分类id
     * @param targetClassId ci分类id
     * @return 关系分类
     */
    List<CcCiClass> filterByVisualModel(Long sourceClassId, Long targetClassId);

    /**
     * 更据关系分类或ci分类查询设计库关系
     * @param rltIdList 关系分类id
     * @param sourceIdList 源端ci分类id
     * @param targetIdList 目标端ci分类id
     * @return 关系
     */
    List<CcCiRltInfo> queryRltByClassIds(Set<Long> rltIdList, Set<Long> sourceIdList, Set<Long> targetIdList);

    /**
     * 更据关系分类或ci分类查询关系
     * @param rltIdList 关系分类id
     * @param sourceIdList 源端ci分类id
     * @param targetIdList 目标端ci分类id
     * @param ownerCode 用户标识
     * @param libType 库
     * @return 关系
     */
    List<CcCiRltInfo> queryRltByClassIds(Set<Long> rltIdList, Set<Long> sourceIdList, Set<Long> targetIdList, String ownerCode, LibType libType);

    /**
     * 根据ciCode及ci分类查询设计库关系
     * @param sourceCiCodes 源端ciCode
     * @param targetCiCodes 目标端ciCode
     * @param sourceClassIds 源端ci分类id
     * @param targetClassIds 目标端ci分类id
     * @return 关系
     */
    List<CcCiRltInfo> queryRltByCodes(Set<String> sourceCiCodes, Set<String> targetCiCodes, List<Long> sourceClassIds, List<Long> targetClassIds);

    /**
     * 根据ciCode及ci分类查询关系
     * @param sourceCiCodes 源端ciCode
     * @param targetCiCodes 目标端ciCode
     * @param sourceClassIds 源端ci分类id
     * @param targetClassIds 目标端ci分类id
     * @param ownerCode 用户标识
     * @param libType 库
     * @return 关系
     */
    List<CcCiRltInfo> queryRltByCodes(Set<String> sourceCiCodes, Set<String> targetCiCodes, List<Long> sourceClassIds, List<Long> targetClassIds, String ownerCode, LibType libType);
}